/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.message.service.postil.impl;

import com.alibaba.fastjson2.JSONObject;
import com.beust.jcommander.internal.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.entity.func.FuncInfo;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.message.vo.app.UserMsgAppInfo;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.FunInfoRpcService;
import com.je.common.base.util.SecurityUserHolder;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.message.service.postil.PostilService;
import com.je.message.vo.PostilVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 批注信息
 */
@Component("postilService")
public class PostilServiceImpl implements PostilService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private FunInfoRpcService funInfoRpcService;
    @Autowired
    private MetaResourceService metaResourceService;

    /**
     * 保存批注实现类
     *
     * @param dynaBean    动态类
     * @return
     */
    @Override
    @Transactional
    public List<DynaBean> savePostil(DynaBean dynaBean) {
        List<DynaBean> lists = new ArrayList<>();
        String pkValue = dynaBean.getStr("POSTIL_MODELID");

        if (StringUtil.isNotEmpty(dynaBean.getStr("POSTIL_HFRID", ""))) {
            String[] hfrIds = dynaBean.getStr("POSTIL_HFRID", "").split(",");
            String[] hfrNames = dynaBean.getStr("POSTIL_HFR", "").split(",");
            metaService.executeSql(" DELETE FROM JE_CORE_POSTIL WHERE POSTIL_HFRID IN (" + StringUtil.buildArrayToString(hfrIds) + ") AND POSTIL_TABLECODE='JE_CORE_POSTIL' AND POSTIL_MODELID='" + dynaBean.getStr("POSTIL_MODELID") + "'");
            for (int i = 0; i < hfrIds.length; i++) {
                String hfrId = hfrIds[i];
                String hfrName = hfrNames[i];
                DynaBean postil = new DynaBean("JE_CORE_POSTIL", true);
                postil.set("POSTIL_PZ", dynaBean.getStr("POSTIL_PZ"));
                postil.set("POSTIL_FUNCID", dynaBean.getStr("POSTIL_FUNCID"));
                postil.set("POSTIL_HFR", hfrName);
                postil.set("POSTIL_HFRID", hfrId);
                postil.set("POSTIL_FUNCCODE", dynaBean.getStr("POSTIL_FUNCCODE"));
                postil.set("POSTIL_TABLECODE", dynaBean.getStr("POSTIL_TABLECODE"));
                postil.set("POSTIL_MODELID", dynaBean.getStr("POSTIL_MODELID"));
                postil.set("POSTIL_FUNCNAME", dynaBean.getStr("POSTIL_FUNCNAME"));
                postil.set("POSTIL_FUNCNR", dynaBean.getStr("POSTIL_FUNCNR"));
                postil.set("POSTIL_FUNCCLS", dynaBean.getStr("POSTIL_FUNCCLS"));
                postil.set("SY_PARENT", dynaBean.getStr("SY_PARENT"));
                commonService.buildModelCreateInfo(postil);
                metaService.insert(postil);
                lists.add(postil);
                String title = postil.getStr("SY_CREATEUSERNAME") + "在" + postil.getStr("SY_CREATETIME") + "，功能【" + postil.getStr("POSTIL_FUNCNAME") + "】给您回复了一条内容!";
                StringBuffer context = new StringBuffer();
                context.append(postil.getStr("SY_CREATEUSERNAME") + "在" + postil.getStr("SY_CREATETIME") + "，功能【<a href=\"javascript:void(0)\" onclick=\"javascript:JE.showFunc('" + dynaBean.getStr("POSTIL_FUNCCODE", "") + "',{type:'form',id:'" + dynaBean.getStr("POSTIL_MODELID", "") + "'});\">" + postil.getStr("POSTIL_FUNCNAME") + "</a>】给您回复了一条内容，");
                context.append("内容：" + dynaBean.getStr("POSTIL_PZ") + "，");
                context.append("详细信息请点击,<a href=\"javascript:void(0)\" onclick=\"javascript:JE.CoreUtil.showPostil({funcCode:'" + dynaBean.getStr("POSTIL_FUNCCODE", "") + "',pkValue:'" + dynaBean.getStr("POSTIL_MODELID", "") + "',userId:'" + SecurityUserHolder.getCurrentAccountRealUser().getId() + "'});\">查看</a>!");

                //发送消息提醒
                if (!SecurityUserHolder.getCurrentAccountRealUser().getId().equals(hfrId)) {
//                    pcMessageService.sendDwr(hfrId, title, context.toString(), "JE.showMsg", "JE.showBatchMsg", true);
                    List<UserMsgAppInfo> userMsgAppInfos = new ArrayList<>();
                    JSONObject params = new JSONObject();
                    params.put("pkValue", dynaBean.getStr("POSTIL_MODELID", ""));
                    UserMsgAppInfo appInfo = new UserMsgAppInfo(postil.getStr("POSTIL_FUNCNAME"), "APPFUNC", dynaBean.getStr("POSTIL_FUNCCODE", ""), "form", params);
                    userMsgAppInfos.add(appInfo);
//                    pcMessageService.sendDwr(hfrId, title, context.toString(), "JE.showMsg", "JE.showBatchMsg", true);
//                    pcMessageService.sendUserMsg(hfrId,title, context.toString(), "PZ",userMsgAppInfos);
                }
            }
        } else {
            commonService.buildModelCreateInfo(dynaBean);
            metaService.insert(dynaBean);
            lists.add(dynaBean);
        }

        //找到批注所有的人然后置未读 推送数字
        List<Map<String, Object>> pzs = metaService.selectSql(" SELECT SY_CREATEUSERID FROM JE_CORE_POSTIL WHERE POSTIL_FUNCCODE='" + dynaBean.getStr("POSTIL_FUNCCODE") + "' AND POSTIL_TABLECODE='" + dynaBean.getStr("POSTIL_TABLECODE") + "' AND POSTIL_MODELID='" + pkValue + "' GROUP BY SY_CREATEUSERID");
        metaResourceService.executeSql(" UPDATE JE_CORE_FUNCEDIT SET FUNCEDIT_NEW='2' WHERE  FUNCEDIT_FUNCCODE='JE_CORE_POSTIL' AND FUNCEDIT_PKVALUE='" + pkValue + "'");
        for (Map pz : pzs) {
            String uId = pz.get("SY_CREATEUSERID") + "";
            //todo 此处微服务改造，先注释
//            userMessageService.push(uId,new String[]{PushType.POSTIL},new String[]{PushAct.ALL});
        }
        //设置创建批注人员的批注为已读
        doDataFuncEdit("JE_CORE_POSTIL", "JE_CORE_POSTIL", pkValue, SecurityUserHolder.getCurrentAccountRealUser().getId(), "0");
        return lists;
    }

    /**
     * 加载批注实现类
     *
     * @param type      类型
     * @param userId    用户id
     * @param keyWord   TODO 暂不明确
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param start     开始页
     * @param limit     没页条数
     * @param returnObj 返回参数
     * @return
     */
    @Override
    public List<PostilVo> loadPostils(String type, String userId, String keyWord, String startDate, String endDate, int start, int limit, JSONObject returnObj) {
        StringBuffer whereSql = new StringBuffer();
        String timeThereSql = "";

        whereSql.append(" AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') ");
        //加入关键字过滤
        if (StringUtil.isNotEmpty(keyWord)) {
            whereSql.append(" AND (POSTIL_FUNCNR LIKE '%" + keyWord + "%' OR POSTIL_PZ LIKE '%" + keyWord + "%' OR SY_CREATEUSERNAME LIKE '%" + keyWord + "%')");
        }
        if (StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)) {
            timeThereSql = " AND SY_CREATETIME>='" + startDate + " 00:00:00' AND SY_CREATETIME <='" + endDate + " 12:59:59'";
            whereSql.append(timeThereSql);
        }
        List<DynaBean> list = metaResourceService.selectByTableCodeAndNativeQueryWithColumns("JE_CORE_FUNCEDIT", NativeQuery.build().eq("FUNCEDIT_USERID", userId).eq("FUNCEDIT_FUNCCODE", "JE_CORE_POSTIL").eq("FUNCEDIT_NEW", "0"), "FUNCEDIT_PKVALUE");
        List<String> idList = Lists.newArrayList();
        for (DynaBean eachBean : list) {
            idList.add(eachBean.getStr("FUNCEDIT_PKVALUE"));
        }

        if ("YD".equals(type)) {
            whereSql.append(" AND POSTIL_MODELID IN (" + StringUtil.buildArrayToString(idList) + ")");
        } else if ("WD".equals(type)) {
            whereSql.append(" AND POSTIL_MODELID NOT IN (" + StringUtil.buildArrayToString(idList) + ")");
        }
//        if(StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)){
//            whereSql.append(" AND SY_CREATETIME>='"+(startDate+" 00:00:00")+"' AND SY_CREATETIME<='"+(endDate+" 23:59:59")+"'");
//        }
        String querySql = " SELECT POS.POSTIL_FUNCCODE,POS.POSTIL_TABLECODE,POS.POSTIL_MODELID,POS.POSTILCOUNT,POS.SY_CREATETIME FROM (SELECT POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID,COUNT(*) POSTILCOUNT,MAX(SY_CREATETIME) SY_CREATETIME FROM JE_CORE_POSTIL WHERE 1=1 " + whereSql.toString() + " GROUP BY POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID) POS ORDER BY POS.SY_CREATETIME DESC";
        String countSql = " SELECT POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID,COUNT(*) POSTILCOUNT,MAX(SY_CREATETIME) SY_CREATETIME FROM JE_CORE_POSTIL WHERE 1=1 " + whereSql.toString() + " GROUP BY POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID ";
        String groupPkSql = " SELECT COUNT(*) FROM JE_CORE_POSTIL WHERE 1=1  AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') " + timeThereSql + "  GROUP BY POSTIL_TABLECODE,POSTIL_MODELID";
        //拼装whereSql
        List<Map<String, Object>> lists = metaService.selectSql(querySql, new String[]{}, start, limit);
        Long totalCount = new Long(lists.size());
        if (limit > 0) {
            try {
                List<Map<String, Object>> result = metaService.selectSql(0, 1, countSql);
                if (result != null && !result.isEmpty()) {
                    totalCount = Long.valueOf(result.get(0).get("POSTILCOUNT").toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //无查询所有数量
        Long allCount = totalCount;
        if (StringUtil.isNotEmpty(keyWord) || !"ALL".equals(type)) {
            allCount = metaService.countBySql(groupPkSql);
        }
        List<PostilVo> postilVos = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        for (Map obj : lists) {
            String tableCode = obj.get("POSTIL_TABLECODE") + "";
            String pkValue = obj.get("POSTIL_MODELID") + "";
            String funcCode = obj.get("POSTIL_FUNCCODE") + "";
            String createTime = obj.get("SY_CREATETIME") + "";
            PostilVo postilVo = new PostilVo();
            //查询出最后批注的信息
            String sql = "SELECT * FROM JE_CORE_POSTIL WHERE POSTIL_FUNCCODE='%s' AND POSTIL_TABLECODE='%s' AND POSTIL_MODELID='%s' ORDER BY  SY_CREATETIME DESC";
            List<Map<String, Object>> lastPostils = metaService.selectSql(String.format(sql, funcCode, tableCode, pkValue));
            if (lastPostils.size() > 0) {
                Map<String, Object> lastPostil = lastPostils.get(0);
                if (lastPostil != null) {
                    postilVo.setLastPostil(lastPostil);
                }
            }
            Integer postilCount = Integer.parseInt(StringUtil.getDefaultValue(obj.get("POSTILCOUNT") + "", "0"));
//            FuncPostilConfig postilConfig=getFuncPostilConfig(funcCode);
//            if(postilConfig==null){
//                continue;
//            }
            FuncInfo funcInfo = funInfoRpcService.getFuncInfo(funcCode);
            DynaBean ywBean = metaService.selectOneByPk(tableCode, pkValue);
            if (ywBean != null) {
                postilVo.setBean(ywBean.getValues());
            }
            postilVo.setFuncName(funcInfo.getFuncName());
            postilVo.setFuncCode(funcInfo.getFuncCode());
            postilVo.setFuncId(funcInfo.getFuncId());
            postilVo.setFuncIconCls(funcInfo.getIconCls());
            postilVo.setShowConfig(funcInfo.getPostilShowConfig());
            postilVo.setTitleConfig(funcInfo.getPostilTitleConfig());
            postilVo.setPostilCount(postilCount);
            postilVo.setCreateTime(createTime);
            postilVo.setPkValue(pkValue);
            postilVo.setTableCode(tableCode);
            postilVos.add(postilVo);
            ids.add(pkValue);
        }

        //处理红点编辑 没有加时间限制
        List<Map<String,Object>> postilList =  metaService.selectSql(" SELECT POSTIL_MODELID FROM JE_CORE_POSTIL WHERE 1=1  AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') " + timeThereSql + "  GROUP BY POSTIL_TABLECODE,POSTIL_MODELID");
        List<String> postilModelIdList = Lists.newArrayList();
        Object eachPostilModelId;
        for (Map<String,Object> eachMap : postilList) {
            eachPostilModelId = eachMap.get("POSTIL_MODELID");
            if(eachPostilModelId != null){
                postilModelIdList.add(eachMap.get("POSTIL_MODELID").toString());
            }
        }
        List<Map<String, Object>> funcEdits = metaResourceService.selectMap("SELECT FUNCEDIT_PKVALUE,FUNCEDIT_USERID,FUNCEDIT_NEW FROM JE_CORE_FUNCEDIT WHERE FUNCEDIT_USERID='" + userId + "' AND FUNCEDIT_FUNCCODE='JE_CORE_POSTIL' AND FUNCEDIT_PKVALUE IN (" + StringUtil.buildArrayToString(postilModelIdList) + ") ");
        Map<String, String> dataVals = new HashMap<>();
        Long readCount = 0L;
        Long noReadCount = 0L;
        for (Map funcEdit : funcEdits) {
            String modelId = funcEdit.get("FUNCEDIT_PKVALUE") + "";
            dataVals.put(modelId, funcEdit.get("FUNCEDIT_NEW") + "");
            if ("0".equals(funcEdit.get("FUNCEDIT_NEW") + "")) {
                readCount++;
            }
        }
        for (PostilVo vo : postilVos) {
            String pkValue = vo.getPkValue();
            if (dataVals.containsKey(pkValue)) {
                vo.setFuncEdit(dataVals.get(pkValue) + "");
            } else {
                vo.setFuncEdit("2");
            }
        }
        noReadCount = allCount - readCount;
        returnObj.put("allCount", allCount);
        returnObj.put("readCount", readCount);
        returnObj.put("noReadCount", noReadCount);
        returnObj.put("totalCount", totalCount);
        return postilVos;
    }

    /**
     * 设置成全部已读实现类
     *
     * @param keyWord like关键字
     */
    @Override
    public void readAllPostil(String keyWord) {
        String userId = SecurityUserHolder.getCurrentAccountRealUser().getId();
        StringBuffer whereSql = new StringBuffer();
        whereSql.append(" AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') ");
        //加入关键字过滤
        if (StringUtil.isNotEmpty(keyWord)) {
            whereSql.append(" AND POSTIL_FUNCNR LIKE '%" + keyWord + "%'");
        }
        List<DynaBean> list = metaResourceService.selectByTableCodeAndNativeQueryWithColumns("JE_CORE_FUNCEDIT", NativeQuery.build().eq("FUNCEDIT_USERID", userId).eq("FUNCEDIT_FUNCCODE", "JE_CORE_POSTIL").eq("FUNCEDIT_NEW", "0"), "FUNCEDIT_PKVALUE");
        List<String> idList = Lists.newArrayList();
        for (DynaBean eachBean : list) {
            idList.add(eachBean.getStr("FUNCEDIT_PKVALUE"));
        }
        whereSql.append(" AND POSTIL_MODELID NOT IN (" + StringUtil.buildArrayToString(idList) + ")");
        String querySql = " SELECT POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID,COUNT(*) POSTILCOUNT,MAX(SY_CREATETIME) SY_CREATETIME FROM JE_CORE_POSTIL WHERE 1=1 " + whereSql.toString() + " GROUP BY POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID ";
        List<Map<String, Object>> lists = metaService.selectSql(querySql);
        for (Map vals : lists) {
            String pkValue = vals.get("POSTIL_MODELID") + "";
            doDataFuncEdit("JE_CORE_POSTIL", "JE_CORE_POSTIL", pkValue, userId, "0");
        }
    }

    public void doDataFuncEdit(String funcCode, String tableCode, String pkValue, String userId, String isNew) {
        DynaBean funcEdit = metaService.selectOne("JE_CORE_FUNCEDIT", ConditionsWrapper.builder()
                .eq("FUNCEDIT_FUNCCODE", funcCode).eq("FUNCEDIT_PKVALUE", pkValue).eq("FUNCEDIT_USERID", userId));
        boolean insertFlag = false;
        if (funcEdit == null) {
            funcEdit = new DynaBean("JE_CORE_FUNCEDIT", true);
            insertFlag = true;
        }
        funcEdit.set("FUNCEDIT_FUNCCODE", funcCode);
        funcEdit.set("FUNCEDIT_TABLECODE", tableCode);
        funcEdit.set("FUNCEDIT_PKVALUE", pkValue);
        funcEdit.set("FUNCEDIT_USERID", userId);
        funcEdit.set("FUNCEDIT_NEW", isNew);
        if (insertFlag) {
            metaService.insert(funcEdit);
        } else {
            metaService.update(funcEdit);
        }
    }
}
